package com.wang.jvm.hotspot.src.share.vm.intepreter;

import com.wang.jvm.hotspot.src.share.tools.DataTranslate;
import com.wang.jvm.hotspot.src.share.tools.Stream;
import com.wang.jvm.hotspot.src.share.vm.memory.StackObj;
import com.wang.jvm.hotspot.src.share.vm.oops.CodeAttributeInfo;
import com.wang.jvm.hotspot.src.share.vm.oops.MethodInfo;
import lombok.Data;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.logging.Logger;

@Data
public class BaseByteCodeStream extends StackObj {
    protected MethodInfo belongMethod;

    protected CodeAttributeInfo belongCode;

    protected int length;

    protected int index;

    protected byte[] codes;

    public int getU1Code() {
        if (index < 0 || index >= length) {
            throw new Error("字节码指令索引超过最大值");
        }
        return Byte.toUnsignedInt(codes[index++]);
    }

    public int getU2Code() {
        if (index < 0 || index >= length) {
            throw new Error("字节码指令索引超过最大值");
        }
        byte[] u2Arr = new byte[2];

        Stream.readU2Simple(codes, index, u2Arr);

        index += 2;

        return DataTranslate.byteArrayToInt(u2Arr);
    }

    public short getUnsignedShort() {
        if (index < 0 || index >= length) {
            throw new Error("字节码指令的索引超过了最大值");
        }

        byte[] u2Arr = new byte[2];

        Stream.readU2Simple(codes, index, u2Arr);

        index += 2;

        return (short) DataTranslate.byteToUnsignedShort(u2Arr);
    }

    public int getU4Code() {
        if (index < 0 || index >= length) {
            throw new Error("字节码指令的索引超过了最大值");
        }

        byte[] arr = new byte[4];

        Stream.readU2Simple(codes, index, arr);
        index += 4;

        ByteBuffer buffer = ByteBuffer.wrap(arr);
        buffer.order(ByteOrder.LITTLE_ENDIAN);

        return buffer.getInt();
    }

    public void reset() {
        index = 0;
    }

    public boolean end() {
        return index >= length;
    }

    public void inc(int step) {
        index +=  step;
    }
}
